/* graphics shape */
/**
 * 直线图基本绘图图形元素定义
 */
'use strict';
/* custom define shape */
/*
 x 站点x坐标
 y 站点y坐标
 text 站点名称
 textPos 站点名称方位
 */
define(function(require , exports , module){
	/**
	 * 站台
	 * @param data
	 * @param layer
	 * @constructor
	 */
	var directionType = {
		"down" :"down",
		"up" : "up"
	}


	var Terminus = function(data,layer){
		this.data = data ;
		this.layer = layer ;
		this.statusType = {
			"Default":"grey",//灰色
			"NotReach":"grey",//灰色
			"Reach" : "#00D200"//绿色
		};
		this.propertyType ={
			"Default":"grey",
			"H" : "yellow", //黄色
			"S" : "#ffffff" //白色
		};
		this.status = {
			"NotReach" :1 ,
			"Reach" : 2
		};

		this.strokeWidth = 4;
		this.fontSize = 18;
		this.shapeGroup = new Kinetic.Group({
			x:this.data.x,
			y:this.data.y,
			//	offsetY:this.data.downUpType === directionType.down ? 60 :-70,
			name:"Terminus"
		});
		this.initEvent();
	};
	/**
	 * 绘制站台
	 */
	Terminus.prototype.draw = function(){
		var $this = this ;
		var lineY = this.data.downUpType ==directionType.down ? 35 : -15;
		this.rectShape = new Kinetic.Rect({
			x:-5,
			y:-5,
			width:this.fontSize*this.data.name.length+15,
			height:this.fontSize+10,
			fill:this.statusType.NotReach
		});
		this.textShape = new Kinetic.Text({
			x:this.data.textPos.x,
			y:this.data.textPos.y,
			text:this.data.name,
			fontSize:this.fontSize,
			fontStyle:"bold",
			fill :"#ffffff"
		});

		this.lineShape = new Kinetic.Line({
			points:[-5,lineY,this.fontSize*this.data.name.length+10,lineY],
			stroke:this.propertyType.Default,
			strokeWidth:this.strokeWidth
		});
		this.shapeGroup.add(this.rectShape);
		this.shapeGroup.add(this.textShape);
		this.shapeGroup.add(this.lineShape);
		this.layer.add(this.shapeGroup);
	};
	/**
	 * 设置站台属性
	 * @param property
	 */
	Terminus.prototype.setProperty = function (property) {
		switch(property){
			case "H":this.lineShape.stroke(this.propertyType.H);
				break;
			case "S":this.lineShape.stroke(this.propertyType.S);
				break;
			default :break;
		}
	};
	/**
	 * 更新站台状态
	 * @param status
	 */
	Terminus.prototype.updateStatus = function(status,code){
		/**
		 * 假设1：未到达，2：到达

		 */
		 var $this = this ;
		switch (status){
			case $this.status.NotReach:
				 $this.rectShape.fill( $this.statusType.NotReach);
				break;
			case $this.status.Reach:			
				 $this.rectShape.fill( $this.statusType.Reach);				 
				break;
			default :
				break;
		}
	};
	/**
	 * 点击站台
	 * @param callback
	 */
	Terminus.prototype.click = function(callback) {
		this.shapeGroup.on("click" , callback);
	};
	/**
	 * 初始化事件
	 */
	Terminus.prototype.initEvent = function(){
		this.shapeGroup.on("mouseover" , function(){
			document.body.style.cursor = "pointer";
		});
		this.shapeGroup.on("mouseout" , function(){
			document.body.style.cursor = "default";
		});
	}
	/**
	 * 区段
	 * @param data
	 * @param layer
	 * @constructor
	 */
	var Segment = function(data , layer) {
		this.x = data.x ;
		this.y = data.y;
		this.code = data.code;
		this.layer = layer;
		this.lineShape;
		this.textShape;
		this.points = data.points;
		this.lineStroke = {
			"Default" : "grey",
			"Occupy" : "#FF2626", //红色
			"Open" : "#00D200",//绿色
			"Free" : "#FFFFFF"//黄色
		}
		this.opStatus={
			"Free" : "free",
			"Occupy" : "occupy",
			"Open" : "open"
		};
		this.textFill = "white";
		this.lineJoin = 'bevel';
		this.data = data;
		this.strokeWidth = 6;
		this.shapeGroup = new Kinetic.Group({
			x         : data.x ,
			y         : data.y,
			name      : "Segment",
			id        : data.code
		});
		this.initEvent();
	};
	/**
	 * 区段线的绘制
	 */
	Segment.prototype.drawLine = function() {
		var $this = this;
		var offset = 0 ;
		if(this.data.direction == directionType.up){
			offset = 1 ;
		}else{
			offset = -1;
		}
		this.lineShape = new Kinetic.Line({
			x           : 0 ,
			y           : 0 ,
			points      : [this.points[0]+offset,this.points[1],this.points[2]-offset,this.points[3]],
			stroke      : this.lineStroke.Default,
			lineJoin    : this.lineJoin,
			id           : this.data.id,
			strokeWidth : this.strokeWidth
		});
		this.shapeGroup.add(this.lineShape);
		this.layer.add(this.shapeGroup);
	};
	/**
	 * 区段文字图形绘制
	 */
	Segment.prototype.drawText = function() {
		var $this = this;
		this.textShape =new Kinetic.Text({
			x: this.data.textPos.x,
			y: this.data.textPos.y,
			text : this.data.id,
			fontSize:this.data.parentId == null ? 14 : 10,
			fill: this.textFill
		})
		this.shapeGroup.add(this.textShape);
		this.layer.add(this.shapeGroup);
	};
	/**
	 * 更新区段状态
	 * @param status
	 */
	Segment.prototype.updateOpStatus = function(opStatus){
		/*假设状态Free：空闲,Occupy：占用，Open：开放*/
		switch (opStatus){
			case this.opStatus.Free :
				this.lineShape.stroke(this.lineStroke.Free);
				break ;
			case this.opStatus.Occupy :
				this.lineShape.stroke(this.lineStroke.Occupy);
				break ;
			case this.opStatus.Open :
				this.lineShape.stroke(this.lineStroke.Open);
				break ;
		}

	};
	/**
	 * 离线/在线
	 * @param isOnline
	 */
	Segment.prototype.updateOnlineStatus = function(isOnline){
		if(!isOnline){
			this.lineShape.stroke(this.lineStroke.Default);
		}
	};
	Segment.prototype.selected = function(layer){
		this.clone = this.lineShape.clone({
			x:this.x,
			y:this.y,
			stroke:"yellow"
		});

		layer.add(this.clone);
		return this.bark(layer);

	};
	Segment.prototype.bark = function(layer){
		var $this = this;
		var timeout = setInterval(function(){
			$this.clone.visible(!$this.clone.isVisible());
			layer.draw();
		},1000);
		return timeout;
	};
	/**
	 * 点击区段
	 * @param callback
	 */
	Segment.prototype.click = function(callback) {
		this.shapeGroup.on("click" , callback);
	};
	/**
	 * 初始化事件
	 */
	Segment.prototype.initEvent = function(){
		this.shapeGroup.on("mouseover" , function(){
			document.body.style.cursor = "pointer";
		});
		this.shapeGroup.on("mouseout" , function(){
			document.body.style.cursor = "default";
		});
	};
	/** 区间绘制对象  **/
	var Section = function(data , layer) {
		this.x = data.x ;
		this.y = data.y;
		this.code = data.code;
		this.layer = layer;
		this.lineShape;
		this.textShape;
		this.points = data.points;
		this.lineStroke = {
			"Default" : "grey",
			"Occupy" : "#FF2626", //红色
			"Open" : "#00D200",//绿色
			"Free" : "#FFFFFF"//黄色
		}
		this.opStatus={
			"Free" : "free",
			"Occupy" : "occupy",
			"Open" : "open"

		};
		this.textFill = "white";
		this.lineJoin = 'bevel';
		this.data = data;
		this.strokeWidth = 6;
		this.shapeGroup = new Kinetic.Group({
			x         : data.x ,
			y         : data.y,
			name      : "Section",
			id        : data.code
		});
		this.initEvent();
	};
	//路线图形绘制
	Section.prototype.drawLine = function() {
		var $this = this;
		var offset = 0 ;
		if(this.data.direction = directionType.down){
			offset = 1 ;
		}else{
			offset = -1;
		}
		this.lineShape = new Kinetic.Line({
			x           : 0 ,
			y           : 0 ,
			points      : [this.points[0]+offset,this.points[1],this.points[2]-offset,this.points[3]],
			stroke      : this.lineStroke.Default,
			lineJoin    : this.lineJoin,
			id           : this.data.id,
			strokeWidth : this.strokeWidth
		});
		this.shapeGroup.add(this.lineShape);
		this.layer.add(this.shapeGroup);
	};
	/**
	 * 区段文字图形绘制
	 */
	Section.prototype.drawText = function() {
		var $this = this;
		this.textShape =new Kinetic.Text({
			x: this.data.textPos.x,
			y: this.data.textPos.y,
			text : this.data.code,
			fontSize:this.data.parentId == null ? 14 : 10,
			fill: this.textFill
		})
		this.shapeGroup.add(this.textShape);
		this.layer.add(this.shapeGroup);
	};
	/**
	 * 更新区段状态
	 * @param opStatus
	 */
	Section.prototype.updateOpStatus = function(opStatus){
		/*假设状态Free：空闲,Occupy：占用，Open：开放*/
		switch (opStatus){
			case this.opStatus.Free :
				this.lineShape.stroke(this.lineStroke.Free);
				break ;
			case this.opStatus.Occupy :
				this.lineShape.stroke(this.lineStroke.Occupy);
				break ;
			case this.opStatus.Open :
				this.lineShape.stroke(this.lineStroke.Open);
				break ;
		}
	};
	/**
	 * 点击区段
	 * @param callback
	 */
	Section.prototype.click = function(callback) {
		this.shapeGroup.on("click" , callback);
	};
	/**
	 * 初始化事件
	 */
	Section.prototype.initEvent = function(){
		this.shapeGroup.on("mouseover" , function(){
			document.body.style.cursor = "pointer";
		});
		this.shapeGroup.on("mouseout" , function(){
			document.body.style.cursor = "default";
		});
	}
	/**
	 * 道岔图形
	 * @param data
	 * @param layer
	 * @constructor
	 */
	var Turnout = function (data , layer) {
		this.data = data;
		this.children = data.children;
		this.layer = layer ;

		this.lineStroke = {
			"Default" : "grey",
			"Occupy" : "#FF2626",
			"Open" : "#00D200",
			"Free" : "#FFFFFF",
			"Error" :"yellow"
		};
		this.opStatus={
			"Free" : "free",
			"Occupy" : "occupy",
			"Open" : "open"

		};
		this.status={
			"Left"  : "left",
			"Right" : "right"
		};

		this.textFill ="#ffffff";
		this.shapeGroup = new Kinetic.Group({
			x         : data.x ,
			y         : data.y,
			name      : "Turnout",
			id        : data.code
		});
		this.initEvent();
	};
	/**
	 * 绘制道岔
	 */
	Turnout.prototype.draw = function(){
		var $this = this ;
		this.textShape =new Kinetic.Text({
			x: this.data.textPos.x,
			y: this.data.textPos.y,
			text : this.data.code,
			fontSize:10,
			fill: this.textFill
		});
		this.shapeGroup.add(this.textShape);
		_.each($this.children,function(turnout){
			var config = {
				x : 0,
				y : 0,
				points:turnout.points,
				lineCap:"sqare",
				stroke:$this.lineStroke.Default,
				strokeWidth :6
			};
			switch (Number(turnout.code)){
				case 1 :
					config.x = turnout.points[2]>0 ? 1:-1;
					$this.line1 = new Kinetic.Line(config);
					break;
				case 2 :
					//定位1
					var length = turnout.points.length;
					$this.line2 = new Kinetic.Line(config);
					break;
				case 3 :
					//定位2
					$this.line3 = new Kinetic.Line(config);
					break;
				default :
					break;
			}
		});

		$this.shapeGroup.add($this.line1);
		$this.shapeGroup.add($this.line2);
		$this.shapeGroup.add($this.line3);
		$this.layer.add($this.shapeGroup);
	};
	/**
	 * 更新道岔状态
	 * @param status
	 */
	Turnout.prototype.updateStatus = function(status){
		//假设：0：定位，1 ：反位， 2：挤岔， 3：四开
		this.shapeArr = [];
		switch (status){
			case this.status.Right :
				this.line1.stroke(this.lineStroke.Free);
				this.line2.stroke(this.lineStroke.Free);
				this.line3.stroke(this.lineStroke.Default);
				this.line1.moveToTop();
				this.line2.moveToTop();
				this.shapeArr.push(this.line1);
				this.shapeArr.push(this.line2);
				break;
			case this.status.Left:
				this.line1.stroke(this.lineStroke.Free);
				this.line2.stroke(this.lineStroke.Default);
				this.line3.stroke(this.lineStroke.Free);
				this.line1.moveToTop();
				this.line3.moveToTop();
				this.shapeArr.push(this.line1);
				this.shapeArr.push(this.line3);
				break;
			case this.status.None:
				this.line1.stroke(this.lineStroke.Default);
				this.line2.stroke(this.lineStroke.Default);
				this.line3.stroke(this.lineStroke.Default);
				this.shapeArr=[];
				break;
			case this.status.Both:
				this.line1.stroke(this.lineStroke.Free);
				this.line2.stroke(this.lineStroke.Free);
				this.line3.stroke(this.lineStroke.Free);
				this.shapeArr=[];
				break;
			default :break;
		}
	};
	Turnout.prototype.updateOpStatus = function(opStatus){
		//假设0： 空闲，1：占用，2：已排进路
		var $this = this;
		switch(opStatus) {
			case this.opStatus.Free:
				_.each($this.shapeArr, function (shape) {
					shape.stroke($this.lineStroke.Free);
				});
				break;
			case this.opStatus.Occupy:
				_.each($this.shapeArr, function (shape) {
					shape.stroke($this.lineStroke.Occupy);
				});
				break;
			case this.opStatus.Open:
				_.each($this.shapeArr, function (shape) {
					shape.stroke($this.lineStroke.Open);
				});
				break;
			default :
				break;
		}
	};
	Turnout.prototype.selected = function(layer , needStatus){
		var $this = this;
		switch (needStatus){
			case  $this.status.Left :
				var config = {
					x: $this.data.x,
					y: $this.data.y,
					stroke:"yellow"
				};
				this.clone1 = $this.line1.clone(config);
				this.clone2 = $this.line3.clone(config);
				break;
			case  $this.status.Right:
				var config = {
					x: $this.data.x,
					y: $this.data.y,
					stroke:"yellow"
				};
				this.clone1 = $this.line1.clone(config);
				this.clone2 = $this.line2.clone(config);
				break;
		}
		layer.add(this.clone1);
		layer.add(this.clone2);
		return this.bark(layer);
	}
	Turnout.prototype.bark = function(layer){
		var $this = this;
		var timeout = setInterval(function(){
			$this.clone1.visible(!$this.clone1.isVisible());
			$this.clone2.visible(!$this.clone2.isVisible());

			layer.draw();
		},1000);
		return timeout;
	};
	/**
	 * 点击道岔
	 * @param callback
	 */
	Turnout.prototype.click = function(callback) {
		this.shapeGroup.on("click" , callback);
	};
	/**
	 * 初始化事件
	 */
	Turnout.prototype.initEvent = function(){
		this.shapeGroup.on("mouseover" , function(){
			document.body.style.cursor = "pointer";
		});
		this.shapeGroup.on("mouseout" , function(){
			document.body.style.cursor = "default";
		});
	}
	/**
	 * 进路表示器
	 * @param data
	 * @param layer
	 * @constructor
	 */
	var RouteIndicator = function(data,layer){
		this.data = data;
		this.layer =layer ;
		this.url = window.location.origin;
		this.ledNum = this.data.type.length;
		this.rootUrl = (this.data.direction ==  directionType.down? "./images/R-1.png" : "./images/R-2.png");
		this.statusType  =  {
			Stop : {
				on: this.url +"/images/R-O-ON.png",
				off:this.url +"/images/R-O-OFF.png",
				failure :this.url +"/images/R-O-OFF.png"
			},
			Straight :{
				on: this.url +"/images/R-S-ON.png",
				off:this.url +"/images/R-S-OFF.png",
				failure :this.url +"/images/R-S-OFF.png"
			},
			Left : {
				on: this.url +"/images/R-L-ON.png",
				off:this.url +"/images/R-L-OFF.png",
				failure :this.url +"/images/R-L-OFF.png"
			},
			Right:{
				on: this.url +"/images/R-R-ON.png",
				off:this.url +"/images/R-R-OFF.png",
				failure :this.url +"/images/R-R-OFF.png"
			}
		};
		this.textFill = {
			None:"grey",
			ON   :"#00D200"
		};
		this.status = {
			"Stop" : "stop",
			"Straight":"straight",
			"Left":"left",
			"Right":"right",
			"None":"none"
		};
		this.shapeGroup = new Kinetic.Group({
			x:data.x,
			y:data.y,
			id:data.code,
			name:"RouteIndicator"
		});
		this.initEvent();
	};
	/**
	 * 绘制进路表示器
	 */
	RouteIndicator.prototype.draw = function(){
		var $this = this;
		var width = 16 ;
		var rootX =10 ;
		var x = $this.data.direction ==  directionType.down ?  0: -rootX;
		//createAnImage(this,x,-8,this.rootUrl);
		_.each($this.data.type  , function(type , i ){
			var x = $this.data.direction ==  directionType.down ? ($this.ledNum-i-1)*width + rootX: -($this.ledNum-i)*width-10;
			switch (type){
				case $this.status.Stop :
					$this.shapeStop = createAnImage($this ,x, 0 , $this.statusType.Stop.off );
					break;
				case $this.status.Left :
					$this.shapeLeft = createAnImage($this ,x, 0 , $this.statusType.Left.off );
					break;
				case $this.status.Straight :
					$this.shapeStraight = createAnImage($this ,x, 0 , $this.statusType.Straight.off );
					break;
				case $this.status.Right :
					$this.shapeRight = createAnImage($this ,x, 0 , $this.statusType.Right.off );
					break;
			}
		});
		this.textShape = new Kinetic.Text({
			x:this.data.textPos.x,
			y:this.data.textPos.y,
			text :this.data.code,
			fontSize:10,
			fill:this.textFill.None
		});
		this.shapeGroup.add(this.textShape);
	};
	/**
	 * 更新进路表示器状态
	 * @param status
	 */
	RouteIndicator.prototype.updateStatus = function(status){
		var $this = this;
		/*假设0：禁止，1：直行开放、2：左转开放、3：右转开放、4：失表*/
		this.textShape.fill(this.textFill.ON);
		switch(status){
			case $this.status.Stop:
				imageUpdateSrc($this.shapeStop , $this.statusType.Stop.on );
				imageUpdateSrc($this.shapeLeft , $this.statusType.Left.off );
				imageUpdateSrc($this.shapeRight , $this.statusType.Right.off );
				imageUpdateSrc($this.shapeStraight , $this.statusType.Straight.off );
				break;
			case $this.status.Straight:
				imageUpdateSrc($this.shapeStop , $this.statusType.Stop.off );
				imageUpdateSrc($this.shapeLeft , $this.statusType.Left.off );
				imageUpdateSrc($this.shapeRight , $this.statusType.Right.off );
				imageUpdateSrc($this.shapeStraight , $this.statusType.Straight.on );
				break;
			case $this.status.Right:
				imageUpdateSrc($this.shapeStop , $this.statusType.Stop.off );
				imageUpdateSrc($this.shapeLeft , $this.statusType.Left.off );
				imageUpdateSrc($this.shapeRight , $this.statusType.Right.on );
				imageUpdateSrc($this.shapeStraight , $this.statusType.Straight.off );
				break;
			case $this.status.Left:
				imageUpdateSrc($this.shapeStop , $this.statusType.Stop.off );
				imageUpdateSrc($this.shapeLeft , $this.statusType.Left.on );
				imageUpdateSrc($this.shapeRight , $this.statusType.Right.off );
				imageUpdateSrc($this.shapeStraight , $this.statusType.Straight.off );
				break;
			case $this.status.None:
				$this.textShape.fill($this.textFill.None);
				imageUpdateSrc($this.shapeStop , $this.statusType.Stop.off );
				imageUpdateSrc($this.shapeLeft , $this.statusType.Left.off );
				imageUpdateSrc($this.shapeRight , $this.statusType.Right.off );
				imageUpdateSrc($this.shapeStraight , $this.statusType.Straight.off );
				break;
			default :break;
		}
	};

	/**
	 * 点击进路表示器
	 * @param callback
	 */
	RouteIndicator.prototype.click = function(callback) {
		this.shapeGroup.on("click" , callback);
	};
	/**
	 * 初始化事件
	 */
	RouteIndicator.prototype.initEvent = function(){
		this.shapeGroup.on("mouseover" , function(){
			document.body.style.cursor = "pointer";
		});
		this.shapeGroup.on("mouseout" , function(){
			document.body.style.cursor = "default";
		});
	}
	/**
	 * 平交道口
	 * @param data
	 * @param layer
	 * @constructor
	 */
	var Crossing = function(data , layer){
		this.data = data ;
		this.layer = layer;
		this.fontSize = 16 ;
		this.fill = "#9797A6";
		this.textLen = this.data.name.length;
		this.shapeGroup = new Kinetic.Group({
			x:this.data.x,
			y:this.data.y,
			name:"Crossing"
		});
		this.statusType = {
			Default:"grey",
			Red:"#FF2626",
			Green:"#00D200"
		};
		this.initEvent();
	};
	/**
	 * 平交道口绘制
	 */
	Crossing.prototype.draw = function(){
		var offset = this.textLen*this.fontSize/2 ;
		this.leftLineShape = new Kinetic.Line({
			x      : -20,
			y      : 0,
			points :[-5,-offset-5,0,-offset,0,offset,-5,offset+5],
			stroke : this.statusType.Default,
			strokeWidth :2
		});
		this.rightLineShape = new Kinetic.Line({
			x      : 20,
			y      : 0,
			points :[5,-offset-5,0,-offset,0,offset,5,offset+5],
			stroke : this.statusType.Default,
			strokeWidth :2
		});
		this.textShape = new Kinetic.Text({
			x:(-this.fontSize-this.textLen)/2,
			y:-offset,
			align:"center",
			fill:this.fill,
			width:this.fontSize+this.textLen,
			text:this.data.name,
			fontSize:this.fontSize,
			fontStyle:"bold"
		});
		this.shapeGroup.add(this.leftLineShape);
		this.shapeGroup.add(this.rightLineShape);
		this.shapeGroup.add(this.textShape);
		this.layer.add(this.shapeGroup);
	};
	/**
	 * 更新平交道口状态
	 * @param status
	 */
	Crossing.prototype.updateStatus = function(status){
		//假设：0：红灯，1：绿灯
		switch(status){
			case 0 :
				this.leftLineShape.stroke(this.statusType.Red);
				this.rightLineShape.stroke(this.statusType.Red);
				break;
			case 1 :
				this.leftLineShape.stroke(this.statusType.Green);
				this.rightLineShape.stroke(this.statusType.Green);
				break;
			default :
				break;
		}
	};
	/**
	 * 点击进路表示器
	 * @param callback
	 */
	Crossing.prototype.click = function(callback) {
		this.shapeGroup.on("click" , callback);
	};
	/**
	 * 初始化事件
	 */
	Crossing.prototype.initEvent = function(){
		this.shapeGroup.on("mouseover" , function(){
			document.body.style.cursor = "pointer";
		});
		this.shapeGroup.on("mouseout" , function(){
			document.body.style.cursor = "default";
		});
	}
	/**
	 * 电车
	 * @param data
	 * @param layer
	 * @constructor
	 */
	var Tram = function(data , layer){
		var $this = this;
		this.data = data ;
		this.layer =layer ;
		this.width = 85;
		this.height = 32;
		this.directionType = {
			"LeftToRight" : "up",
			"RightToLeft" : "down"
		};
		this.shapeGroup = new Kinetic.Group({
			x:this.data.x -this.width/2,
			y:this.data.y - this.height/2,
			offsetY:this.data.direction == this.directionType.LeftToRight  ? -70 : 70 ,
			name:"Tram"
		});
		this.timeFill ={
			"Default":"#ffffff",
			"Advance":"#00D200",
			"Nomal":"#00BFFF",
			"Late":"#FF2626"
		}
		this.fill="#9797A6";
		this.serviceFill = "#000000";
		this.codeFill = "#FFA64C";
		this.textSize = 9;
		this.stroke = "yellow";
		this.strokeWidth = 2;
		this.space = 3;
		this.bodyHeight =this.height -this.space*2 ;
		this.bodyWidth = this.width-this.space*2-this.bodyHeight;
	};
	/**
	 * 绘制电车
	 */
	Tram.prototype.draw = function(){
		this.tramShape = new Kinetic.Rect({
			width:this.width,
			height:this.height,
			stroke:this.stroke,
			fill :"grey",
			strokeWidth:this.strokeWidth
		});
		this.headShape = new Kinetic.Path({
			x:this.data.direction == this.directionType.LeftToRight ? this.width-this.space : this.space,
			y:this.space,
			data:this.data.direction == this.directionType.LeftToRight ?"m"+0+","+this.bodyHeight+"h"+(-this.bodyHeight)+"v"+(-this.bodyHeight)+"z":"m"+0+","+this.bodyHeight+"h"+this.bodyHeight+"v"+(-this.bodyHeight)+"z",
			fill: this.timeFill.Late
		});

		this.bodyShape = new Kinetic.Rect({
			x:this.data.direction == this.directionType.LeftToRight ? this.space : this.bodyHeight+this.space,
			y:this.space,
			width:this.bodyWidth,
			height:this.bodyHeight,
			fill:"#ffffff"
		});
		this.serviceShape = new Kinetic.Text({
			x:this.data.direction == this.directionType.LeftToRight ? this.space : this.bodyHeight+this.space ,
			y:3,
			text:this.data.serviceNum,
			fill:this.serviceFill,
			fontSize:this.textSize,
			align:"center"
		});

		this.codeShape = new Kinetic.Text({
			x:this.data.direction == this.directionType.LeftToRight ? this.space : this.bodyHeight+this.space+20,
			y:16,
			text:this.data.tramCode,
			fill:this.serviceFill,
			fontSize:this.textSize,
			align:"center"
		});
		this.timeShape = new Kinetic.Text({
			x:this.data.direction == this.directionType.LeftToRight ? this.bodyHeight+this.space+10 : this.bodyHeight+this.space ,
			y:16,
			text:this.data.time,
			fill:this.timeFill.Late,
			fontSize:this.textSize,
			align:"center"
		});
		this.shapeGroup.add(this.tramShape);
		this.shapeGroup.add(this.headShape);
		this.shapeGroup.add(this.bodyShape);
		this.shapeGroup.add(this.serviceShape);
		this.shapeGroup.add(this.codeShape);
		this.shapeGroup.add(this.timeShape);
		this.layer.add(this.shapeGroup);
	};
	/**
	 * 更新电车属性及状态
	 * @param data
	 */
	Tram.prototype.refresh = function(data){
		var $this = this;
		this.data = data;
		this.shapeGroup.x(this.data.x -this.width/2);
		this.shapeGroup.y(this.data.y - this.height/2);
		this.shapeGroup.offsetY(this.data.direction == this.directionType.LeftToRight  ? -70 : 70);
		this.headShape.x(this.data.direction == this.directionType.LeftToRight ? this.width-this.space : this.space);
		this.headShape.data(this.data.direction == this.directionType.LeftToRight ?"m"+0+","+this.bodyHeight+"h"+(-this.bodyHeight)+"v"+(-this.bodyHeight)+"z":"m"+0+","+this.bodyHeight+"h"+this.bodyHeight+"v"+(-this.bodyHeight)+"z");
		this.bodyShape.x(this.data.direction == this.directionType.LeftToRight ? this.space : this.bodyHeight+this.space);
		this.serviceShape.x(this.data.direction == this.directionType.LeftToRight ? this.space : this.bodyHeight+this.space);
		this.serviceShape.text(this.data.serviceNum);
		this.codeShape.x(this.data.direction == this.directionType.LeftToRight ? this.space : this.bodyHeight+this.space+20);
		this.codeShape.text(this.data.tramCode);
		this.timeShape.x(this.data.direction == this.directionType.LeftToRight ? this.bodyHeight+this.space+10 : this.bodyHeight+this.space );
		this.timeShape.text(this.data.time);
	};
	/**
	 * 尽头线
	 * @param data
	 * @param layer
	 * @constructor
	 */
	var EndNode = function(data , layer){
		this.data = data ;
		this.layer = layer ;
		this.shapeGroup = new Kinetic.Group({
			x : this.data.x ,
			y : this.data.y ,
			name:"Group"
		});
		this.stroke = "#ffffff";
		this.strokeWidth = 6;
	};
	/**
	 * 绘制尽头线
	 */
	EndNode.prototype.draw =function(){
		this.nodeShape = new Kinetic.Path({
			data:this.data.direction == 0 ? "m0,0h-10v-10h-10M-10,0v10h-10" :"m0,0h10v-10h10M10,0v10h10" ,
			stroke:this.stroke,
			strokeWidth:this.strokeWidth
		});
		this.shapeGroup.add(this.nodeShape);
		this.layer.add(this.shapeGroup);

	};
	/**
	 * 道岔表示器
	 * @param data
	 * @param layer
	 * @constructor
	 */
	var TurnoutIndicator = function(data,layer){
		this.data = data;
		this.layer =layer ;
		this.url = window.location.origin;
		this.ledNum = this.data.type.length;
		this.rootUrl = (this.data.direction ==  directionType.down? this.url +"/images/R-1.png" : this.url+"/images/R-2.png");
		this.statusType  =  {
			Stop : {
				on: this.url +"/images/T-O-ON.png",
				off:this.url +"/images/T-O-OFF.png",
				failure :this.url +"/images/R-O-OFF.png"
			},
			Left : {
				on: this.url +"/images/T-L-ON.png",
				off:this.url +"/images/T-L-OFF.png",
				failure :this.url +"/images/T-L-OFF.png"
			},
			Right:{
				on: this.url +"/images/T-R-ON.png",
				off:this.url +"/images/T-R-OFF.png",
				failure :this.url +"/images/T-R-OFF.png"
			}
		};
		this.textFill = {
			None:"grey",
			ON   :"#00D200"
		};
		this.status = {
			"Stop" : "stop",
			"Straight":"straight",
			"Left":"left",
			"Right":"right",
			"None":"none"
		};
		this.shapeGroup = new Kinetic.Group({
			x:data.x,
			y:data.y,
			id:data.code,
			name:"TurnoutIndicator"
		});
		this.initEvent();
	};
	/**
	 * 绘制道岔表示器
	 */
	TurnoutIndicator.prototype.draw = function(){
		var $this = this;
		var width = 16 ;
		var rootX = 10;
		var x = $this.data.direction ==  directionType.down ?  0: -rootX;
		createAnImage(this,x,-8,this.rootUrl);
		_.each($this.data.type  , function(type , i ){
			var x = $this.data.direction ==  directionType.down ? ($this.ledNum-i-1)*width + rootX: -($this.ledNum-i)*width-10;
			switch (type){
				case $this.status.Stop :
					$this.shapeStop = createAnImage($this ,x, 0 , $this.statusType.Stop.off );
					break;
				case $this.status.Left :
					$this.shapeLeft = createAnImage($this ,x, 0 , $this.statusType.Left.off );
					break;
				case $this.status.Right :
					$this.shapeRight = createAnImage($this ,x, 0 , $this.statusType.Right.off );
					break;
			}
		});
		this.textShape = new Kinetic.Text({
			x:this.data.textPos.x,
			y:this.data.textPos.y,
			text :this.data.code,
			fontSize:10,
			fill:this.textFill.None
		});
		this.shapeGroup.add(this.textShape);
	};
	/**
	 * 更新道岔表示器状态
	 * @param status
	 */
	TurnoutIndicator.prototype.updateStatus = function(statusStr){
		var $this = this;
		var statusArr = statusStr.split(",");
		this.textShape.fill(this.textFill.ON);
		if(statusArr.length == 0 && statusArr[0]!== $this.status.Stop){
			imageUpdateSrc($this.shapeStop, $this.statusType.Stop.off);
		}
		_.each(statusArr , function(status){
			switch(status) {
				case $this.status.Stop:
					imageUpdateSrc($this.shapeStop, $this.statusType.Stop.on);
					break;
				case $this.status.Straight:
					imageUpdateSrc($this.shapeLeft, $this.statusType.Left.off);
					imageUpdateSrc($this.shapeRight, $this.statusType.Right.on);
					break;
				case $this.status.Left:
					imageUpdateSrc($this.shapeLeft, $this.statusType.Left.on);
					imageUpdateSrc($this.shapeRight, $this.statusType.Right.off);
					break;
				case $this.status.None:
					$this.textShape.fill($this.textFill.None);
					imageUpdateSrc($this.shapeStop, $this.statusType.Stop.off);
					imageUpdateSrc($this.shapeLeft, $this.statusType.Left.off);
					imageUpdateSrc($this.shapeRight, $this.statusType.Right.off);
					break;
				default :
					break;
			}
		});
	};
	/**
	 * 点击道岔表示器
	 * @param callback
	 */
	TurnoutIndicator.prototype.click = function(callback) {
		this.shapeGroup.on("click" , callback);
	};
	/**
	 * 初始化事件
	 */
	TurnoutIndicator.prototype.initEvent = function(){
		this.shapeGroup.on("mouseover" , function(){
			document.body.style.cursor = "pointer";
		});
		this.shapeGroup.on("mouseout" , function(){
			document.body.style.cursor = "default";
		});
	};
	var Marking =function(data , layer){
		this.data = data ;
		this.layer = layer ;
		this.shapeGroup = new Kinetic.Group({
			x : this.data.x ,
			y : this.data.y,
			name:"Marking"
		});
		this.stroke = "black";

	};
	Marking.prototype.draw = function(){
		this.line = new Kinetic.Line({
			points:this.data.points,
			stroke:this.stroke,
			dash:this.data.dash
		});
		this.shapeGroup.add(this.line);
		this.layer.add(this.shapeGroup);
	}
	/**
	 * 生成一张图片
	 * @param object
	 * @param x
	 * @param y
	 * @param url
	 * @returns {Image|*}
	 */
	var createAnImage = function( object , x , y  ,url ){
		//	object.imageObj = new Image();
		object.imageObj = new Kinetic.window.Image();
		object.imageObj.onload = (function(object , x , y  ,url){
			object.image = new Kinetic.Image({
				x:x,
				y:y,
				image:object.imageObj,
				width:object.width,
				height:object.height
			});
			object.shapeGroup.add(object.image);
			object.layer.add(object.shapeGroup);
			object.layer.draw();
		})(object , x , y  ,url);
		object.imageObj.src = url;

		return object.imageObj;
	};
	/**
	 * 改变图片链接
	 * @param shape
	 * @param src
	 */
	var imageUpdateSrc = function( shape , src  ){
		if(shape !=null && shape.src !== src){
			return shape.src = src ;
		}
	};
	exports.EndNode = EndNode;
	exports.Tram = Tram;
	exports.Crossing = Crossing;
	exports.Terminus = Terminus;
	exports.Section = Section;
	exports.Segment = Segment;
	exports.Turnout = Turnout;
	exports.RouteIndicator = RouteIndicator;
	exports.TurnoutIndicator = TurnoutIndicator;
	exports.Marking = Marking;
});
